Sensor Porting Guide

Version 0.3


This document describes how to porting SigmaStar sensor driver including basic hardware knowledge, software control sensor API (sensor handle), sensor interface API (Sensor-IF) of SigmaStar and software porting flow. In this document, we take the sensor driver of imx415/imx335/sc2315/sc2335 as examples. You can follow the instructions in this document to complete the sensor porting step by step.

First we introduce the relevant knowledge of hardware and corresponding source code to make it easier to understand for you.


1.1. Sensor power sequence

Check the power-on sequence spec in the sensor datasheet. Please follow below power sequence 1.1V > 1.8V > 2.9V as the imx415 sensor datasheet required.

Figure 1: the IMX415 sensor power sequence spec

Table 1: the IMX415 sensor power sequence timing table

  • Corresponding source code

    You can control sensor power-on and reset pins through “handle->pCus_sensor_poweron” in the sensor driver handle initial function. If you need to modify sensor power sequence timing, please check the characteristics of sensor and hardware design.

    static int pCus_poweron(ms_cus_sensor *handle, u32 idx)  {
        ISensorIfAPI *sensor_if = &handle->sensor_if_api;
        //Sensor power on sequence
        sensor_if->PowerOff(idx, handle->pwdn_POLARITY);   // Powerdn Pull Low
        sensor_if->Reset(idx, handle->reset_POLARITY);     // Rst Pull Low
        sensor_if->SetIOPad(idx, handle->sif_bus, handle->interface_attr.attr_mipi.mipi_lane_num);
        sensor_if->SetCSI_Clk(idx, CUS_CSI_CLK_216M);
        sensor_if->SetCSI_Lane(idx, handle->interface_attr.attr_mipi.mipi_lane_num, ENABLE);
        sensor_if->SetCSI_LongPacketType(idx, 0, 0x1C00, 0);
        if (handle->interface_attr.attr_mipi.mipi_hdr_mode == CUS_HDR_MODE_SONY_DOL)
            sensor_if->SetCSI_hdr_mode(idx, handle->interface_attr.attr_mipi.mipi_hdr_mode, 1);
    
        sensor_if->PowerOff(idx, !handle->pwdn_POLARITY);
        //Sensor board PWDN Enable, 1.8V & 2.9V need 30ms then Pull High
        SENSOR_MSLEEP(31);
        sensor_if->Reset(idx, !handle->reset_POLARITY);
        SENSOR_UDELAY(1);
        sensor_if->MCLK(idx, 1, handle->mclk);
        SENSOR_DMSG("Sensor Power On finished\n");
        return SUCCESS;
    }
    

NOTE: Below is SigmaStar Sensor board schematic of power circuit. 1.1V, 1.8V, 2.9V power will pull high after power-on enable. First 1.1V, then 1.8V and 2.9V, you can use an oscilloscope to measure it on your sensor board.

Figure 2: the IMX415 sensor power circuit


1.2. Sensor IC slave address check

SigmaStar SoC needs to communicate with a sensor through I2C, please check the sensor I2C slave address first.

Table 2: the IMX415 sensor slave id table

NOTE: Check the sensor board schematic of I2C slave mode Option

Figure 3: the IMX415 sensor board I2C slave mode

  • Corresponding source code

    The sensor driver I2C Setting in Marco define

    ////////////////////////////////////
    // I2C Info                         //
    ////////////////////////////////////
    #define SENSOR_I2C_ADDR     0x34        //I2C slave address
    #define SENSOR_I2C_SPEED    300000      //I2C speed, 60000~320000
    //#define SENSOR_I2C_CHANNEL   1        //I2C Channel
    //#define SENSOR_I2C_PAD_MODE  2        //Pad/Mode Number
    #define SENSOR_I2C_LEGACY  I2C_NORMAL_MODE  //usually set CUS_I2C_NORMAL_MODE,  if use old OVT I2C protocol=> set CUS_I2C_LEGACY_MODE
    #define SENSOR_I2C_FMT     I2C_FMT_A16D8 //CUS_I2C_FMT_A8D8, CUS_I2C_FMT_A8D16, CUS_I2C_FMT_A16D8, CUS_I2C_FMT_A16D16
    

NOTE: Sensor-IF of I2C control Interface in handle initial function

handle->i2c_cfg.mode     = SENSOR_I2C_LEGACY;    //(CUS_ISP_I2C_MODE) FALSE;
handle->i2c_cfg.fmt      = SENSOR_I2C_FMT;       //CUS_I2C_FMT_A16D16;
handle->i2c_cfg.address  = SENSOR_I2C_ADDR;      //0x34;
handle->i2c_cfg.speed    = SENSOR_I2C_SPEED;     //300000;

1.3. Sensor MCLK support

Each sensor can support in different MCLK. That the MCLK list table that we can provide is as follows. You can find the MCLK corresponding to the sensor from the initialization settings provided by the sensor vendor. The sensor MCLK Setting in Marco define

  • Corresponding source code

    ////////////////////////////////////
    // MCLK Info                        //
    ////////////////////////////////////
    /*******I5/MACARON Support MCLK List*******
    *    CUS_CMU_CLK_27MHZ   / CUS_CMU_CLK_21P6MHZ  / CUS_CMU_CLK_12MHZ,
    *    CUS_CMU_CLK_5P4MHZ  / CUS_CMU_CLK_36MHZ    / CUS_CMU_CLK_54MHZ,
    *    CUS_CMU_CLK_43P2MHZ / CUS_CMU_CLK_61P7MHZ  / CUS_CMU_CLK_72MHZ,
    *    CUS_CMU_CLK_48MHZ    / CUS_CMU_CLK_24MHZ    / CUS_CMU_CLK_37P125MHZ,
    ******End of Support MCLK List*******/
    #define Preview_MCLK_SPEED           CUS_CMU_CLK_27MHZ
    #define Preview_MCLK_SPEED_HDR_DOL  CUS_CMU_CLK_37P125MHZ
    

    NOTE: The sensor MCLK control Interface in handle initial function

    ////////////////////////////////////
    //    mclk                        //
    ////////////////////////////////////
    handle->mclk                   = UseParaMclk(SENSOR_DRV_PARAM_MCLK());
    

2. Sensor porting relevant software control

After introducing the relevant knowledge of hardware and corresponding source code, we will introduce software control API (sensor handle) and sensor interface API (Sensor-IF) of SigmaStar in this part.


2.1. Sensor driver support mode define

Register the sensor support behavior mode. For example, the IMX415 sensor supports linear and HDR mode, you can refer to the IMX415 sensor driver and fill it in define of “SENSOR_DRV_ENTRY_IMPL_END_EX”.

SENSOR_DRV_ENTRY_IMPL_END_EX(  IMX415_HDR,
                            cus_camsensor_init_handle,
                            cus_camsensor_init_handle_hdr_dol_sef,
                            cus_camsensor_init_handle_hdr_dol_lef,
                            imx415_params
                            );

Table 3: the sensor driver “SENSOR_DRV_ENTRY_IMPL_END_EX” define

Parameter Describe
Name Sensor Name and support mode
LinearEntry Sensor Linear mode handle initial function
HdrSefEntry Sensor HDR Short Exposure handle initial function
HdrLefEntry Sensor HDR Long Exposure handle initial function
PrivateDataType Sensor Private Data Type

2.1.1. Introduce “SENSOR_DRV_IMPL_END_EX”

You can check macro define “SENSOR_DRV_ENTRY_IMPL_END_EX” more detail in the path “driver/SensorDriver/drv/inc/drv_sensor_common.h”. LinearEntry has a group of private data set, HdrSefEntry and HdrLefEntry have another a group of private data set.

#define SENSOR_DRV_ENTRY_IMPL_END_EX (Name,LinearEntry,HdrSefEntry,HdrLefEntry,PrivateDataType)\
static PrivateDataType* g_pData[2][MAX_CAMID_LEN] = { {0,0,0,0}, {0,0,0,0} };\
int Name##_init_driver(unsigned char chmap)\
{\
    int nCamID=0;\
    /*To avoid compile warning*/\
    void* p0 = LinearEntry;\
    void* p1 = HdrSefEntry;\
    void* p2 = HdrLefEntry;\
    if(DrvSensorHandleVer(CUS_CAMSENSOR_HANDLE_MAJ_VER, CUS_CAMSENSOR_HANDLE_MIN_VER)==FAIL)\
    return FAIL;\
    if(DrvSensorIFVer(CUS_CAMSENSORIF_MAJ_VER, CUS_CAMSENSORIF_MIN_VER)==FAIL)\
    return FAIL;\
    if(DrvSensorI2CVer(CUS_CAMSENSOR_I2C_MAJ_VER, CUS_CAMSENSOR_I2C_MIN_VER)==FAIL)\
    return FAIL;\
    for(nCamID=0;nCamID<MAX_CAMID_LEN;++nCamID)\
    {\
        if((chmap>>nCamID)&0x1)\
        {\
            if(p0){\
                void* pData = CamOsMemAlloc(sizeof(PrivateDataType));\
                memset(pData,0,sizeof(PrivateDataType));\
                DrvRegisterSensorDriverEx(nCamID, LinearEntry,pData);\
                DrvRegisterSensorI2CSlaveID(nCamID, (i2c_slave_id>>(nCamID*8))&0xFF);\
                SENSOR_DMSG("Connect %s linear to sensor pad %d\n",__FUNCTION__, nCamID);\
                g_pData[0][nCamID] = pData;\
            }\
            if(p1||p2){\
                void* pData = CamOsMemAlloc(sizeof(PrivateDataType));\
                memset(pData,0,sizeof(PrivateDataType));\
                if(p1){\
                    DrvRegisterPlaneDriverEx(nCamID, 1, HdrSefEntry,pData);\
                    DrvRegisterPlaneI2CSlaveID(nCamID, 1, (i2c_slave_id>>(nCamID*8))&0xFF);\
                    SENSOR_DMSG("Connect %s SEF to vif sensor pad %d\n",__FUNCTION__, nCamID);\
                }\
                if(p2){\
                    DrvRegisterPlaneDriverEx(nCamID, 0, HdrLefEntry,pData);\
                    DrvRegisterPlaneI2CSlaveID(nCamID, 1, (i2c_slave_id>>(nCamID*8))&0xFF);\
                    SENSOR_DMSG("Connect %s LEF to sensor pad %d\n",__FUNCTION__, nCamID);\
                }\
                g_pData[1][nCamID] = pData;\
            }\
        }\
    }\
    return 0;\
}\

2.2. Sensor driver handle function

Next we will introduce and explain handle API in the linear and HDR handle initial functions. We can control, set or read any state of the sensor through the handle API. Here we take the sensor driver of imx415 as an example. You can step through the sensor porting of linear and HDR mode according to the instructions in this document.

2.2.1. Handle of IC API

Set I2C hardware information

Table 4: handle of I2C API define

Parameter Describe NOTE
handle->i2c_cfg.mode Register I2C Mode I2C_NORMAL_MODE /**\< Sensor driver can only use I2C_NORMAL_MODE */ I2C_LEGACY_MODE, /**\< Do not use */
handle->i2c_cfg.fmt Register set I2C format for bit of address & data length. /**\< I2C_FMT_A16D8 means 16 bits Address, 8 bits Data */ I2C_FMT_A8D8, I2C_FMT_A16D8, I2C_FMT_A8D16, I2C_FMT_A16D16, I2C_FMT_END /**\< Reserved */
handle->i2c_cfg.address Register set sensor I2C slave address, SigmaStar SoC supports 8bits slave address Check From Sensor Datasheet
handle->i2c_cfg.speed Register set sensor max I2C speed (MACARON fixed at 300 KHz) I2C speed, 60000~320000

2.2.2. Handle of MCLK API

Set the sensor MCLK information

Table 5: handle of MCLK API define

handle->mclk Register set VIF module output MCLK to sensor For MI Query!! Main Chip Support MCLK List as : CUS_CMU_CLK_27MHZ, CUS_CMU_CLK_21P6MHZ, CUS_CMU_CLK_12MHZ, CUS_CMU_CLK_5P4MHZ, CUS_CMU_CLK_36MHZ, CUS_CMU_CLK_54MHZ, CUS_CMU_CLK_43P2MHZ, CUS_CMU_CLK_61P7MHZ, CUS_CMU_CLK_72MHZ, CUS_CMU_CLK_48MHZ, CUS_CMU_CLK_24MHZ, CUS_CMU_CLK_37P125MHZ, CUS_CMU_CLK_LPLL_DIV1, CUS_CMU_CLK_LPLL_DIV2, CUS_CMU_CLK_LPLL_DIV4, CUS_CMU_CLK_LPLL_DIV8,

2.2.3. Handle of Sensor model id API

Set sensor name and mode information

Table 6: handle of model id API define

Parameter Describe NOTE
handle->model_id Register set sensor model for libcamera user by using MIPI IMX415_MIPI
PARALLEL IMX323_PARL
HDR IMX415_MIPI_HDR_SEF IMX415_MIPI_HDR_LEF

2.2.4. Handle of sensor interface and output hardware information

Table 7: handle of Sensor interface and output hardware information API define

Parameter Describe NOTE
handle->pCus_sensor_poweron Fill Up Sensor IF Info!!! Register set sensor power-on sequence function. Function ref : pCus_poweron
handle->pCus_sensor_init Register load sensor initial setting function.
handle->pCus_sensor_post_init Set and enable SoC mipi csi status. Special case is like SmartSens product SC4236/SC2315
handle->isp_type Register ISP type (not used in MACARON) SENSOR_ISP_TYPE ISP_SOC, /**\< Not support */ ISP_EXT, /**\< sensor without built-in ISP */
handle->sif_bus Register set sensor interface bus type SENSOR_IFBUS_TYPE CUS_SENIF_BUS_PARL = 0, /**\< sensor data bus is parallel */ CUS_SENIF_BUS_MIPI = 1, /**\< sensor data bus is mipi */ CUS_SENIF_BUS_BT601 = 2, CUS_SENIF_BUS_BT656 = 3, CUS_SENIF_BUS_BT1120 = 4,
handle->data_prec Register set sensor output raw data precision SENSOR_DATAPREC CUS_DATAPRECISION_8 = 0, /**\< raw data precision 8bits */ CUS_DATAPRECISION_10 = 1, /**\< raw data precision 10bits */ CUS_DATAPRECISION_16 = 2, /**\< raw data precision 16bits */ CUS_DATAPRECISION_12 = 3, /**\< raw data precision 12bits */ CUS_DATAPRECISION_14 = 4, /**\< raw data precision 14bits */
handle->data_mode Register set sensor bayer raw (8/10-bits) to 12-bits mode (Not used in MACARON) SENSOR_DATAMODE CUS_SEN_8TO12_7074, CUS_SEN_8TO12_7000, CUS_SEN_8TO12_114118, CUS_SEN_8TO12_11400, CUS_SEN_10TO12_9098, CUS_SEN_10TO12_9000, CUS_SEN_10TO12_1121110, CUS_SEN_10TO12_11200
handle->bayer_id Register set sensor bayer raw start id SENSOR_BAYERID CUS_BAYER_RG = 0, CUS_BAYER_GR, CUS_BAYER_BG, CUS_BAYER_GB,
handle->RGBIR_id Register set sensor RGB-IR start id

#If NOT RGB-IR sensor, please set CUS_RGBIR_NONE
SENSOR_RGBIRID CUS_RGBIR_NONE = 0, CUS_RGBIR_R0 = 1, CUS_RGBIR_G0 = 2, CUS_RGBIR_B0 = 3, CUS_RGBIR_G1 = 4, CUS_RGBIR_G2 = 5, CUS_RGBIR_I0 = 6, CUS_RGBIR_G3 = 7, CUS_RGBIR_I1 = 8
handle->orient Register get sensor image mirror-flip default status SENSOR_ORIT CUS_ORIT_M0F0, /**\< mirror, flip unchanged */ CUS_ORIT_M1F0, /**\< mirror changed */ CUS_ORIT_M0F1, /**\< flip changed */ CUS_ORIT_M1F1, /**\< mirror and flip changed */
handle->snr_pad_group Register sensor pad group CUS_SENSOR_PAD_GROUP_A = 0, CUS_SENSOR_PAD_GROUP_B = 1, CUS_SENSOR_PAD_GROUP_A = 0, CUS_SENSOR_PAD_GROUP_B = 1,
handle->snr_pad_mode Register sensor master and slave mode CUS_SENSOR_MASTER_MODE = 0, CUS_SENSOR_SLAVE_MODE = 1,
handle->ir_only_fmt Register sensor ir format status
For HDR (MIPI) Interface
handle->interface_attr.attr_mipi.mipi_lane_num Register set MIPI lane number Default : 4
handle->interface_attr.attr_mipi.mipi_data_format Register set MIPI data format CUS_SEN_INPUT_FORMAT_YUV422, CUS_SEN_INPUT_FORMAT_RGB,
handle->interface_attr.attr_mipi.mipi_yuv_order Register set MIPI yuv order For yuv sensor only
handle->interface_attr.attr_mipi.mipi_hsync_mode Register set HDR virtual channel0 hsync mode SENSOR_MIPI_HSYNC_MODE PACKET_HEADER_EDGE1 = 0, /**\< packet header edge */ PACKET_HEADER_EDGE2 = 1, /**\< line end edge */ PACKET_HEADER_EDGE3 = 2, /**\< line start edge */ PACKET_FOOTER_EDGE = 3, /**\< packet footer edge */
handle->interface_attr.attr_mipi.mipi_hdr_mode Register set MIPI HDR mode CUS_HDR_MODE_NONE = 0, CUS_HDR_MODE_SONY_DOL = 1, CUS_HDR_MODE_DCG = 2, CUS_HDR_MODE_EMBEDDED_RAW8 = 3, CUS_HDR_MODE_EMBEDDED_RAW10 = 4, CUS_HDR_MODE_EMBEDDED_RAW12 = 5, CUS_HDR_MODE_EMBEDDED_RAW16 = 6, //Only for OV2718? CUS_HDR_MODE_LI = 7,
handle->interface_attr.attr_mipi. mipi_sampling_delay MIPI CLK skip time (ns) (Not used in MACARON)
handle->interface_attr.attr_mipi.mipi_hdr_virtual_channel_num Register set HDR virtual channel number #Based on each sensor VC mode header define For example imx415: Long Exposure Frame : 0 Short Exposure Frame : 1

2.2.5. Handle of signal polarity API

Set SoC hardware signal polarity

Table 8: handle of signal polarity API define

Parameter Describe NOTE
handle->pwdn_POLARITY Register set output sensor power-down pin (GPIO) polarity SENSOR_PWDN_POL CUS_CLK_POL_POS = 0, /**\< High active */ CUS_CLK_POL_NEG /**\< Low active */
handle->reset_POLARITY Register set output sensor reset pin (GPIO) polarity SENSOR_RST_POL CUS_CLK_POL_POS = 0, /**\< High active */ CUS_CLK_POL_NEG /**\< Low active */
For Parallel Interface
handle->VSYNC_POLARITY Register set receive sensor Vsync pin signal polarity SENSOR_VSYNC_POL CUS_CLK_POL_POS = 0, /**\< High active */ CUS_CLK_POL_NEG /**\< Low active */
handle->HSYNC_POLARITY Register set receive sensor Hsync pin signal polarity SENSOR_HSYNC_POL CUS_CLK_POL_POS = 0, /**\< High active */ CUS_CLK_POL_NEG /**\< Low active */
handle->PCLK_POLARITY Register set receive sensor pixel clk pin signal polarity SENSOR_PCLK_POL CUS_CLK_POL_POS = 0, /**\< High active */ CUS_CLK_POL_NEG /**\< Low active */

2.2.6. Handle of sensor resolution capability API

Set sensor support and implement output image information.

Table 9: handle of sensor resolution capability API define

Parameter Describe NOTE
handle->video_res_supported.num_res Register set sensor support resolution number
handle->video_res_supported.ulcur_res Register set sensor current resolution Default : 0
handle->video_res_supported.res[n].width Register set sensor support width
handle->video_res_supported.res[n].height Register set sensor support height
handle->video_res_supported.res[n].max_fps Register set sensor support preview maximum fps
handle->video_res_supported.res[n].min_fps Register set sensor support preview minimum fps
handle->video_res_supported.res[n].crop_start_x Register set VIF crop sensor output image start of X
handle->video_res_supported.res[n].crop_start_y Register set VIF crop sensor output image start of Y
handle->video_res_supported.res[n].nOutputWidth Register set VIF output active pixel
handle->video_res_supported.res[n].nOutputHeight Register set VIF output active line
handle->video_res_supported.res[n].strResDesc Register set sensor resolution & fps string EX: 1920x1080\@30fps

2.2.7. Handle of set/get sensor control API

We can load sensor initial setting, switch sensor output resolution, sensor mirror or flip and fps set or get through these functions.

Table 10: handle of set/get sensor control API define

Parameter Describe NOTE
handle->pCus_sensor_release Register sensor release function. Function ref : cus_camsensor_release_handle
handle->pCus_sensor_init Register load sensor initial setting function. Function ref : pCus_init_mipi4lane_linear
handle->pCus_sensor_poweron Register set sensor power-on sequence function. Function ref : pCus_poweron
handle->pCus_sensor_poweroff Register set sensor power-off sequence function. Function ref : pCus_poweroff
handle->pCus_sensor_GetSensorID Register get and check sensor ID Function ref : pCus_GetSensorID
handle->pCus_sensor_GetVideoResNum Register get sensor support resolution number function, that’s video output index. Function ref : pCus_GetVideoResNum
handle->pCus_sensor_GetVideoRes Register get sensor support preview info function (width, height, and frame rate). Function ref : pCus_GetVideoRes
handle->pCus_sensor_GetCurVideoRes Register get sensor current preview info function (width, height, and frame rate). Function ref : pCus_GetCurVideoRes
handle->pCus_sensor_SetVideoRes Register switch sensor and load initial setting function. Function ref : pCus_SetVideoRes
handle->pCus_sensor_GetOrien Register get sensor mirror-flip status function. Function ref : pCus_GetOrien
handle->pCus_sensor_SetOrien Register set Sensor mirror-flip status function. Function ref : pCus_SetOrien
handle->pCus_sensor_GetFPS Register get sensor FPS status function. Function ref : pCus_GetFPS
handle->pCus_sensor_SetFPS Register set sensor FPS status function. Function ref : pCus_SetFPS
handle->pCus_sensor_SetPatternMode Set sensor test pattern (Color Bar Pattern).

2.2.8. Handle of set/get sensor AE control API

First we will introduce the sensor driver private data in this part, this purpose is to record the parameters of the sensor without any modification. Here is imx415 as a reference example. The naming can be customized according to each sensor or developer, and there is no mandatory requirement.

Table 11: example for imx415 private data

Parameter Describe NOTE
params->tGain_reg Register set each frame sensor AE gain parameter. For imx415 Linear
params->tExpo_reg Register set each frame sensor exposure line parameter. For imx415 Linear
params->tVts_reg Register set each frame sensor total line parameter. For imx415 Linear, LEF
params->tSHR0_reg Register set each frame long exposure frame shutter time. For imx415 LEF
params->tRHS1_reg Register set each frame readout time of short exposure frame. For imx415 SEF
params->tSHR1_reg Register set each frame short exposure frame shutter time. For imx415 SEF
params->tGain_hdr_dol_lef_reg Register set each frame long exposure frame HDR AE Gain. For imx415 LEF
params->tGain_hdr_dol_sef_reg Register set each frame short exposure frame HDR AE Gain. For imx415 SEF
params->expo.vts Register set each frame total line. For imx415 Linear, LEF
params->expo.expo_lines Register set each frame exposure line. For imx415 Linear, LEF
params->expo.fps Register set sensor fps. For imx415 Linear, LEF
OTHERS

We can set or get sensor AE function status through this API, including AE shutter time, gain, limit AE setting value and AE update timing, etc.

Table 12: handle of set/get sensor AE control API define

Parameter Describe NOTE
handle->ae_gain_delay Register set sensor AE Gain effective frame after setting frame. Based On Sensor Characteristic Please check *SUPPLYMENT4.2
handle->ae_shutter_delay Register set sensor AE Shutter effective frame after setting frame. Based On Sensor Characteristic Please check *SUPPLYMENT4.2
handle->ae_gain_ctrl_num Register set sensor AE Gain table number. Linear mode set to 1 HDR mode set to 2
handle->ae_shutter_ctrl_num Register set sensor AE Shutter table number. Linear mode set to 1 HDR mode set to 2
handle->sat_mingain Register get sensor Initial minimum Gain. Minimum Gain != 1
handle->pCus_sensor_AEStatusNotify Register update AE Gain, Shutter and fps status at frame start or frame end. Function Ref : pCus_AEStatusNotify Status 0 is frame end update Status 1 is frame start update
handle->pCus_sensor_GetAEUSecs Register get sensor output image exposure time. Function Ref : pCus_GetAEUSecs
handle->pCus_sensor_SetAEUSecs Register set sensor output image exposure time. Function Ref : pCus_SetAEUSecs
handle->pCus_sensor_GetAEGain Register get sensor AE Gain. Function Ref : pCus_GetAEGain
handle->pCus_sensor_SetAEGain Register set sensor AE Gain. Function Ref : pCus_SetAEGain
handle->pCus_sensor_GetAEMinMaxGain Register get sensor minimum & maximum Gain information Function Ref : pCus_GetAEMinMaxGain
handle->pCus_sensor_GetAEMinMaxUSecs Register get sensor minimum & maximum exposure time Function Ref : pCus_GetAEMinMaxUSecs
handle->pCus_sensor_GetShutterInfo Register get sensor minimum & maximum exposure in line, and shutter step Function:

2.2.9. Sensor-IF API

SENSOR_IF API for Connect with the sensor driver and the VIF driver, this callback control in below handle control function.

We will introduce and describe this API, more detail you can reference the sensor driver of IMX415.

Parameter Describe NOTE
sensor_if->PowerOff Set Sensor-IF PowerDown pull high or not. Callback to VIF driver
sensor_if->Reset Set Sensor-IF SW RESET pull high or not. Callback to VIF driver
sensor_if->MCLK Set VIF Output MCLK Callback to VIF driver
sensor_if->SetIOPad For SENSOR-IF I/O Bus Mode Callback to VIF driver
sensor_if->QueryMCLK For query sensor master clock Callback to VIF driver
sensor_if->QueryLaneNum For query sensor MIPI lane number Callback to VIF driver
sensor_if->SetSkipFrame Skip vif output frame Callback to VIF driver
For MIPI Interface
sensor_if->SetCSI_Clk Set MIPI Interface MAC CLK Callback to VIF driver
sensor_if->SetCSI_Lane Set MIPI Interface Data Lane Callback to VIF driver
sensor_if->SetCSI_hdr_mod Set HDR Data Format Callback to VIF driver
sensor_if->SetCSI_LongPacketType Set MIPI Long Packet Type Callback to VIF driver
sensor_if->SetCSI_clk_data_skip Skip hs clock when into HSRX mode Callback to VIF driver
sensor_if->VCOHsmode Callback to VIF driver

3. Software porting flow

This chapter introduces the process of software porting sensor driver. First, it will explain how to initialize the sensor. Then describe the information required by the sensor driver 3A and control the functions that 3A will call.


3.1. The sensor driver initial flow introduction

Figure 4: porting the sensor driver flow

This document introduces the initial process of transplanting the sensor according to the process in the figure above.

3.1.1. Set the sensor information setting

These settings are the hardware information of the sensor, we have listed the necessary hardware information, you can refer to the IMX415 / IMX335 sensor driver,

////////////////////////////////////
// Sensor-If Info                 //
////////////////////////////////////
//MIPI config begin.
#define SENSOR_MIPI_LANE_NUM        (lane_num)          //IMX335 Linear mode supports MIPI 2/4 Lane
#define SENSOR_MIPI_LANE_NUM_DOL    (4) //(hdr_lane_num)//IMX335 DOL mode supports MIPI 4 Lane
//#define SENSOR_MIPI_HDR_MODE        (0) //0: Non-HDR mode. 1:Sony DOL mode

#define SENSOR_ISP_TYPE             ISP_EXT             //ISP_EXT, ISP_SOC (Non-used)
//#define SENSOR_DATAFMT             CUS_DATAFMT_BAYER    //CUS_DATAFMT_YUV, CUS_DATAFMT_BAYER
#define SENSOR_IFBUS_TYPE           CUS_SENIF_BUS_MIPI  //CFG //CUS_SENIF_BUS_PARL, CUS_SENIF_BUS_MIPI
#define SENSOR_MIPI_HSYNC_MODE      PACKET_HEADER_EDGE1
#define SENSOR_MIPI_HSYNC_MODE_HDR_DOL PACKET_FOOTER_EDGE
#define SENSOR_DATAPREC             CUS_DATAPRECISION_10
#define SENSOR_DATAPREC_DOL         CUS_DATAPRECISION_10
#define SENSOR_DATAMODE             CUS_SEN_10TO12_9098  //CFG
#define SENSOR_BAYERID              CUS_BAYER_RG         //0h: CUS_BAYER_RG, 1h: CUS_BAYER_GR, 2h: CUS_BAYER_BG, 3h: CUS_BAYER_GB
#define SENSOR_BAYERID_HDR_DOL     CUS_BAYER_RG
#define SENSOR_RGBIRID              CUS_RGBIR_NONE
#define SENSOR_ORIT                 CUS_ORIT_M0F0        //CUS_ORIT_M0F0, CUS_ORIT_M1F0, CUS_ORIT_M0F1, CUS_ORIT_M1F1,
//#define SENSOR_YCORDER              CUS_SEN_YCODR_YC     //CUS_SEN_YCODR_YC, CUS_SEN_YCODR_CY
//#define long_packet_type_enable     0x00 //UD1~UD8 (user define)

////////////////////////////////////
// MCLK Info                        //
////////////////////////////////////
#define Preview_MCLK_SPEED          CUS_CMU_CLK_27MHZ//CUS_CMU_CLK_37P125MHZ//CUS_CMU_CLK_27MHZ
#define Preview_MCLK_SPEED_HDR_DOL  CUS_CMU_CLK_27MHZ

3.1.2. Set the sensor IC setting

SoC communicates with sensors mainly through I2C. Therefore, you need to set I2C before sending sensor setting value to the sensor.

Please refer to this document chapter 1.2.

3.2. Set support image resolution information

You need to fill in the sensor image information provided by the sensor provider FAE. This information includes preview size, image crop size and site etc. We define this information as a global variable.

////////////////////////////////////
// Image Info                     //
////////////////////////////////////
static struct {     // LINEAR
    // Modify it based on number of support resolution
    enum {LINEAR_RES_1 = 0, LINEAR_RES_2, LINEAR_RES_3, LINEAR_RES_4, LINEAR_RES_5, LINEAR_RES_6, LINEAR_RES_7, LINEAR_RES_8, LINEAR_RES_END}mode;
    // Sensor Output Image info
    struct _senout{
        s32 width, height, min_fps, max_fps;
    }senout;
    // VIF Get Image Info
    struct _sensif{
        s32 crop_start_X, crop_start_y, preview_w, preview_h;
    }senif;
    // Show resolution string
    struct _senstr{
        const char* strResDesc;
    }senstr;
}imx415_mipi_linear[] = {
    {LINEAR_RES_1, {3860, 2250, 3, 20}, {0, 0, 3840, 2160}, {"3840x2160@20fps"} },
    {LINEAR_RES_2, {3096, 2190, 3, 30}, {0, 0, 3072, 2048}, {"3072x2048@30fps"} }, // Modify it
    {LINEAR_RES_3, {3096, 1758, 3, 30}, {0, 0, 3072, 1728}, {"3072x1728@30fps"} }, // Modify it
    {LINEAR_RES_4, {2616, 1974, 3, 30}, {0, 0, 2592, 1944}, {"2592x1944@30fps"} }, // Modify it
    {LINEAR_RES_5, {2976, 1686, 3, 30}, {0, 0, 2944, 1656}, {"2944x1656@30fps"} }, // Modify it
    {LINEAR_RES_6, {2592, 1470, 3, 30}, {0, 0, 2560, 1440}, {"2560x1440@30fps"} }, // Modify it
    {LINEAR_RES_7, {1920, 1080, 3, 60}, {0, 0, 1920, 1080}, {"1920x1080@60fps"} }, // Modify it
    {LINEAR_RES_8, {3864, 2192, 3, 30}, {0, 0, 3840, 2160}, {"3840x2160@30fps"} }, // Modify it
    //{LINEAR_RES_9, {2616, 1974, 3, 25}, {0, 0, 2592, 1944}, {"2592x1944@25fps"} }, // Modify it
};

3.2.1. The sensor power on sequence function

Please refer to this document chapter 1.1.

3.2.2. The sensor initial function

Here is the initial setting of the sensor through the i2c device, first read the product ID or sensor ID of the sensor device to ensure that the correct sensor is used. Please refer to the function registered by “handle->pCus_sensor_init”.

3.2.3. Select the sensor output resolution function

MI will get the image resolution information supported by the sensor driver and select one of the sensor's initial settings.

Please refer to the function registered by “handle->pCus_sensor_SetVideoRes”.


3.3. Implement the sensor control function

The functions that the sensor driver needs to support include fps adjustment, AE shutter adjustment, AE gain adjustment, and mirror flip function settings, which we will not describe more detail, because this needs to be implemented according to the characteristics of each sensor.

The following is our control the sensor implement function flow. Relatively, we also need to get the sensor information, please refer to the figure below:

Figure 5: control the sensor implement function flow

Figure 6: get the sensor implement function information or status

3.3.1. AE shutter control and get AE shutter information

How to control AE shutter, please refer to the function registered by “handle->pCus_sensor_SetAEUSecs”.

Also, ISP algo or MI need to get AE shutter information, please refer to the function registered by “handle->pCus_sensor_GetAEUSecs” and “handle->pCus_sensor_GetShutterInfo”.

3.3.2. AE gain control and get AE gain information

How to control AE gain, please refer to the function registered by “handle->pCus_sensor_SetAEGain”.

Also, ISP algo or MI need to get AE gain information, please refer to the function registered by “handle->pCus_sensor_GetAEGain” and “handle->pCus_sensor_GetAEMinMaxGain”.

3.3.3. Sensor frame rate control and get sensor frame rate information

How to control the sensor output frame rate, please refer to the function registered by “handle->pCus_sensor_SetFPS”.

Also, MI needs to get the sensor output frame rate information, please refer to the function registered by “handle->pCus_sensor_GetFPS”.

3.3.4. Sensor mirror-flip control and get sensor mirror-flip information

How to control the sensor image mirror-flip, please refer to the function registered by “handle->pCus_sensor_SetOrien”.

Also, MI needs to get the sensor image mirror-flip information, please refer to the function registered by “handle->pCus_sensor_GetOrien”.

3.4. IC execution time control

The above AE shutter, AE gain, sensor frame rate and mirror control, we hope everyone can send commands to the sensor through I2C at the same time

So we will implement this using the function "handle->pCus_sensor_AEStatusNotify"

Therefore, we can control the time of I2C send commands to the sensor through two parameters "CUS_FRAME_ACTIVE" and "CUS_FRAME_INACTIVE". Most sensors can be set at the frame start, so the parameter "CUS_FRAME_ACTIVE" can be selected.

Figure 7: I2C execution time

NOTE:

If the porting sensor cannot find out what caused the image abnormality, you can call “return success” directly in the function.

3.4.1. Sensor AE shutter/gain delay count

How to set “handle->ae_shutter_delay” and “handle->ae_gain_delay”, please refer to this document chapter 4.2.

3.5. Sensor AE shutter/gain delay count

How to set “handle->ae_gain_ctrl_num” and “handle->ae_shutter_ctrl_num”, please refer to this document chapter 2.2.8.


4. Supplyment


4.1. Install the Sensor Driver and parameter introduce

SigmaStar sensor driver provides several installation parameters that can be used when installing the sensor driver. Here are the parameters and instructions as below:

Table 13: sensor driver install parameter

Parameter Describe
chmap Specify SoC Channel pad for sensor
lane_num Specify Sensor linear mode MIPI lane number
hdr_lane_num Specify Sensor hdr mode MIPI lane number
i2c_slave_id Specify Sensor i2c slave id

For example:

insmod imx335_MIPI.ko chmap=1 lane_num=4 hdr_lane_num=4 i2c_slave_id=0x20

If the above parameters are not used when installing the sensor driver, the default values ​​in the sensor driver are used.


4.2. Verify and debug video stream

The next step is to verify that the sensor driver can be used normally, so, you need to copy app from “/sdk/verify/mi_demo/out/demo/app” to EVB, I take “prog_cus3a” as an example:

/customer # ./prog_cus3a
use default sensor pad 0, vif dev 0
Use HDR ?
0 not use, 1 use DOL
0
You select not use HDR client [548] connected, module:sensor
index 0, Crop(0,0,3840,2160), outputsize(3860,2250), maxfps 20, minfps 3, ResDesc 3840x2160@20fps
index 1, Crop(0,0,3072,2048), outputsize(3096,2190), maxfps 30, minfps 3, ResDesc 3072x2048@30fps
index 2, Crop(0,0,3072,1728), outputsize(3096,1758), maxfps 30, minfps 3, ResDesc 3072x1728@30fps
index 3, Crop(0,0,2592,1944), outputsize(2616,1974), maxfps 30, minfps 3, ResDesc 2592x1944@30fps
index 4, Crop(0,0,2944,1656), outputsize(2976,1686), maxfps 30, minfps 3, ResDesc 2944x1656@30fps
index 5, Crop(0,0,2560,1440), outputsize(2592,1470), maxfps 30, minfps 3, ResDesc 2560x1440@30fps
index 6, Crop(0,0,1920,1080), outputsize(1920,1080), maxfps 60, minfps 3, ResDesc 1920x1080@60fps
index 7, Crop(0,0,3840,2160), outputsize(3864,2192), maxfps 30, minfps 3, ResDesc 3840x2160@30fps
choice which resolution use, cnt 8

4.2.1. Check frame interval

At the same time you can open telnet and enter the following cmd to confirm the VIF and ISP status.

Usually 30fps means that a frame period is 33.3ms.

/ # cat /sys/class/mstar/vif0/vif_ints
== VIF CH-0 ==
Interval(ns)                    : 33309000
VREF_RISING                   : 6147
VREF_FALLING                  : 6149
LINE_CNT_0                    : 2
LINE_CNT_1                    : 2

4.2.2. Check the sensor output stream status

Confirm the information of the sensor signal received by VIF device

/ # cat /sys/class/mstar/vif0/vif_info
== VIF CH-0 ==
INTF_MODE = 4
CH_EN: 1
SRC: MIPI0
INPUT_FMT: RGB
PIX_FMT: 12 bits
HDR_EN: 0
HDR_CH: VC0
CROP_EN: 1
CROP_START_X: 0 - 1919
CROP_START_Y: 0 - 1079
PIXEL_CNT: 1920
LINE_CNT: 1080

4.2.3. Check the ISP status

If the transmission speed of one line or pixel per frame is too fast, even if the VIF can receive the image data normally, there is no guarantee that the ISP can process it immediately, it causes isp fifo full.

/ # cat /sys/class/mstar/isp0/isp_ints
frame_count                     : 1089
u32FrameIntervalNanoSec         : 33332 us
ISP_FIFO_FULL                   : 0
INT_PIPE1_FIFO_FULL             : 0
ISP_BUSY                        : 1089, 06.952374
ISP_IDLE                         : 1090, 06.950575
RDMA0_DONE                     : 0
RDMA1_DONE                     : 0
WDMA0_DONE                    : 0
WDMA1_DONE                    : 0
WDMA6_LINE_HIT                  : 0
WDMA6_DONE                     : 0
ISPIF_VSYNC                       : 1089, 06.952046, 0
AE_DONE                         : 1088, 06.950279, 1934
AE_DONE period                  : 31565 us

4.3. Verify shutter and gain delay

If you want to verify that the sensor AE gain/shutter delay, you can use apitool, also follow the steps below to control the sensor AE gain/shutter function step by step.

STEP 1. You need to execute process of mixer first

/customer # ./mixer -q -n 1          (linear mode)
/customer # ./mixer -q -n 1 -N 3_2    (hdr mode)

STEP 2. Open IQ tool in sdk path “project/tools/apitool”

STEP 3. Host Name is EVB’s IP address, check it then connect to EVB

STEP 4. Select Macaron AE option, and select “ExposureMode” menu table to M_Mode

Step 5. Adjust “DebugLev” menu and set AE Debug Level from 0 to 64, then you can check you console log

Check the AE message shown on the console

Step 6. Adjust AE sensor gain or shutter manually. At the same time, you can observe the AE message shown on the console.

Observer the value of “CurYx10” change from 308 to 1436

After we set the gain of AE through ISP tool, it will take effect in the next frame. The CurYx10 represents the brightness information of a previous frame. The following figure is an example. The AE gain delay needs to set 2.

Figure 8: AE Y value response time


4.4. Verify shutter and gain linearity

If you want to verify that the sensor AE gain/shutter function is normal after porting the sensor AE gain/shutter function finish, you can use apitool. You can follow the steps below to control the sensor AE gain/shutter function step by step.

STEP 1. You need to execute process of mixer

/customer # ./mixer -q -n 1        (linear mode)
/customer # ./mixer -q -n 1 -N 3_2    (hdr mode)

STEP 2. Open IQ tool in sdk path “project/tools/apitool”

STEP 3. Host Name is EVB’s IP address, check it then connect to EVB

STEP 4. Select Macaron AE option, and select “ExposureMode” menu table to M_Mode

Step 5. Adjust AE sensor gain and shutter manually. At the same time, you can observe image changes through VLC or your debug message.

The IQ Tool has defined upper and lower limit for the AE settings, you can adjust it according to your needs. You can reference Exposure limit table.


4.5. Skip frame feature

The sensor driver that has been implemented has imx307. You can refer to the sensor driver of imx307. Here I will briefly explain how to use skip frame function.

Step 1. Add a variable "skip _cnt" inside Params structure of sensor driver

u32 max_rhs1;
    u32 lef_shs2;
    u32 skip_cnt;
    bool dirty;
    bool change;
    I2C_ARRAY tVts_reg[3];
    I2C_ARRAY tGain_reg[3];
    I2C_ARRAY tExpo_reg[3]; 
    I2C_ARRAY tShs2_reg[3];
    I2C_ARRAY tRhs1_reg[3];
    I2C_ARRAY tGain_hdr_dol_lef_reg[1];
    I2C_ARRAY tGain_hdr_dol_sef_reg[1];
    bool orien_dirty;
} imx307_params;

Step 2. Set the number of skip frames in the function that needs to skip frames.

For an example of imx307, in HDR mode, it may flicker when changing fps (from 10 fps to 30 fps) in high brightness environment, so skip 1 frame to avoid flicker.

if(params->expo.expo_lines > 2 * params->expo.vts - params->max_rhs1 -3){
    vts = (params->expo.expo_lines + params->max_rhs1 + 3 + 1) / 2;
    }else{
    vts = params->expo.vts;
    }

    params->expo.vts = vts;
    pCus_SetAEUSecsHDR_DOL_SEF1(handle, params->expo.expo_sef_us);
    params->skip_cnt = 1;
    return SUCCESS;

Step 3. The actual time to skip frame in function of “AESStatusNotify”. Please add the following features. SensorIF will calculate the time to set the VIF mask disable based on the number of skip frames and the current fps time period.

            if(params->skip_cnt){
                sensor_if->SetSkipFrame(handle->snr_pad_group, params->expo.fps, params->skip_cnt);
                params->skip_cnt = 0;
            }
            break;
        default :
            break;
    }
    return SUCCESS;

4.6. Sensor post initial feature (Special case for SmartSens)

Since the Smartsens sensor first transmit i2c cmd after power-on, the probability of the sensor mipi csi and clock will be pulled down, it leads to SoC mipi csi abnormal.

Figure 9: Smartsense sensor signal

Currently, the solution is to change the sequence of the sensor power-on and the sensor initialization. After the sensor initialize completed, then enable SoC mipi csi to resolve this problem. Please refer to the following process:

Figure 10: power on sequence flow change